package chen.web.forum;

import java.util.List;

import chen.web.cache.CacheUtils;
import chen.web.forum.Subject.TopRank;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;

public class TopTopicCachedTopicManager extends BaseTopicManagerProxy implements TopicManager {

	private static final String TopTopicInfoCacheName = "TopTopicInfoCache";
	private static Cache TopTopicInfoCache = null;
	
	public TopTopicCachedTopicManager(TopicManager tm) {
		super(tm);
		// TODO Auto-generated constructor stub
		CacheConfiguration config = new CacheConfiguration(TopTopicInfoCacheName, 1000)
			.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
			.eternal(false)
			.diskPersistent(false);
		TopTopicInfoCache = new Cache(config);
		CacheManager.create().addCache(TopTopicInfoCache);
		CacheUtils.storeDescription(TopTopicInfoCache, "缓存置顶主题信息");
	}

	@Override
	public List<TopicInfo> getTopicInfoList(SubjectCondition condition,
			int beginOffset, int count) {
		// TODO Auto-generated method stub
		//缓存置顶主题列表
		if(condition.getType() == SubjectCondition.SubjectType.top){
			condition.lock();
			Element elem = TopTopicInfoCache.get(condition);
			if(elem == null){
				List<TopicInfo> topicInfoList = super.getTopicInfoList(condition, beginOffset, count);
				TopTopicInfoCache.put(new Element(condition, topicInfoList));
				return topicInfoList;
			} else {
				return (List<TopicInfo>) elem.getValue();
			}
		}
		return super.getTopicInfoList(condition, beginOffset, count);
	}
	
	private void clearCache(Category cat){
		List<SubjectCondition> keys = TopTopicInfoCache.getKeys();
		for(SubjectCondition key : keys){
			Category temp = cat;
			while(temp != null){
				if(key.getCategory().getId() == temp.getId()){
					TopTopicInfoCache.remove(key);
				}
				temp = temp.getParent();
			}
		}
	}
	
	@Override
	public Subject restore(Subject subject) {
		// TODO Auto-generated method stub
		Subject result = super.restore(subject);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
		}
		return result;
	}

	@Override
	public Subject cancelTop(Subject subject) {
		// TODO Auto-generated method stub
		Subject result = super.cancelTop(subject);
		clearCache(subject.getCategory());	
		return result;
	}

	@Override
	public void delete(Subject subject) {
		// TODO Auto-generated method stub
		super.delete(subject);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
		}
	}

	@Override
	public void increaseViewCount(Subject subject) {
		// TODO Auto-generated method stub
		List<SubjectCondition> keys = TopTopicInfoCache.getKeys();
		for(SubjectCondition key : keys){
			Category temp = subject.getCategory();
			while(temp != null){
				if(key.getCategory().getId() == temp.getId()){
					Element elem = TopTopicInfoCache.get(key);
					List<TopicInfo> list = (List<TopicInfo>) elem.getValue();
					for(TopicInfo info : list){
						if(info.getId() == subject.getId()){
							synchronized(this){
								info.setViewCount(info.getViewCount()+1);	
							}
						}
					}
				}	
				temp = temp.getParent();
			}
		}
		super.increaseViewCount(subject);
	}

	@Override
	public Subject setDigest(Subject subject, boolean digest) {
		// TODO Auto-generated method stub
		Subject result = super.setDigest(subject, digest);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
		}
		return result;
	}

	@Override
	public Subject setTop(Subject subject, TopRank rank) {
		// TODO Auto-generated method stub
		Subject result = super.setTop(subject, rank);
		clearCache(subject.getCategory());
		return result;
	}

	@Override
	public void update(Subject subject) {
		// TODO Auto-generated method stub
		super.update(subject);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
		}
	}

	@Override
	public Subject move(Subject subject, Category category)
			throws NotLowestException {
		// TODO Auto-generated method stub
		Subject result = super.move(subject, category);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
			clearCache(category);	
		}
		return result;
	}

	@Override
	public boolean safeDelete(Subject subject) {
		// TODO Auto-generated method stub
		boolean result = super.safeDelete(subject);
		if(subject.isTop()){
			clearCache(subject.getCategory());	
		}
		return result;
	}
	
	
}
